package yanglib.session;

import java.util.LinkedList;
import java.util.List;
import java.util.TreeMap;

/**
 * Created with IntelliJ IDEA.
 * User: user
 * Date: 9/12/14
 * Time: 9:01 PM
 * To change this template use File | Settings | File Templates.
 */
public class TimeoutChecker extends Thread {
    private TreeMap<Long, LinkedList<PendingRequest>> toCheck = new TreeMap<Long, LinkedList<PendingRequest>>();
    private boolean running = true;
    int count = 0;

    public synchronized void add(PendingRequest pRequest){
        count ++;
        //System.out.println("check size = "+toCheck.size()+" "+count);
        long timeoutTime = pRequest.getTimeOutTime();
        if(!toCheck.containsKey(timeoutTime)){
            toCheck.put(timeoutTime, new LinkedList<PendingRequest>());
        }
        toCheck.get(timeoutTime).add(pRequest);
    }

    public synchronized void remove(PendingRequest pRequest){
        count--;
        //System.out.println("check size2 = "+toCheck.size()+" "+count);
        long timeoutTime = pRequest.getTimeOutTime();
        toCheck.get(timeoutTime).remove(pRequest);
        if(toCheck.get(timeoutTime).size() == 0)
            toCheck.remove(timeoutTime);
    }

    public synchronized void reset(PendingRequest pRequest, long timeout){
        this.remove(pRequest);
        pRequest.resetTimeout(timeout);
        this.add(pRequest);
    }

    public void run(){
        while(running){
            long toSleep = 50;
            synchronized(this){
                if(toCheck.size()>0){
                    System.out.println("check timeout");
                    long timeoutTime = toCheck.firstKey();
                    LinkedList<PendingRequest> list = toCheck.get(timeoutTime);
                    if(timeoutTime > System.currentTimeMillis()){
                        toSleep = timeoutTime - System.currentTimeMillis();
                    }
                    else{
                        for(PendingRequest pRequest : (List<PendingRequest>)list.clone()){
                            pRequest.getCallback().timeout(pRequest);
                        }
                    }
                }
                else{
                    System.out.println("No timeout to check");
                }
            }
            try{
                Thread.sleep(toSleep);
            }
            catch(InterruptedException e){
                e.printStackTrace();
                return;
            }
        }
    }
}
